"""
SSL连接修复模块
解决Windows环境下的SSL连接问题，确保HTTPS请求正常工作
"""
import ssl
import certifi
import requests
import urllib3
import os
import sys
from urllib3.util import ssl_ as ssl_util
from urllib3.util.ssl_ import create_urllib3_context

def disable_ssl_warnings():
    """禁用SSL警告"""
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def create_ssl_context():
    """创建安全的SSL上下文"""
    try:
        # 使用certifi提供的证书
        context = ssl.create_default_context(cafile=certifi.where())
        context.check_hostname = True
        context.verify_mode = ssl.CERT_REQUIRED
        
        # 设置支持的TLS版本
        context.minimum_version = ssl.TLSVersion.TLSv1_2
        context.maximum_version = ssl.TLSVersion.TLSv1_3
        
        # 设置密码套件
        context.set_ciphers('ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS')
        
        return context
    except Exception as e:
        print(f"创建SSL上下文失败: {e}")
        # 如果创建失败，返回一个更宽松的上下文
        context = ssl.create_default_context()
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
        return context

def patch_urllib3_ssl():
    """修补urllib3的SSL上下文创建"""
    try:
        # 创建自定义的SSL上下文函数
        def create_urllib3_context_patched(ssl_version=None, cert_reqs=None, options=None, ciphers=None):
            context = create_ssl_context()
            if ssl_version:
                context.minimum_version = ssl_version
            if cert_reqs is not None:
                context.verify_mode = cert_reqs
            if ciphers:
                context.set_ciphers(ciphers)
            return context
        
        # 替换urllib3的SSL上下文创建函数
        ssl_util.create_urllib3_context = create_urllib3_context_patched
        return True
    except Exception as e:
        print(f"修补urllib3 SSL失败: {e}")
        return False

def configure_requests_session():
    """配置requests会话，确保SSL正常工作"""
    try:
        # 创建会话
        session = requests.Session()
        
        # 设置SSL配置
        session.verify = certifi.where()
        
        # 设置适配器
        from requests.adapters import HTTPAdapter
        from urllib3.util.retry import Retry
        adapter = HTTPAdapter(
            max_retries=Retry(
                total=3,
                backoff_factor=1,
                status_forcelist=[500, 502, 503, 504]
            )
        )
        session.mount('https://', adapter)
        session.mount('http://', adapter)
        
        # 设置请求头
        session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
        })
        
        return session
    except Exception as e:
        print(f"配置requests会话失败: {e}")
        return requests.Session()

def setup_ssl_environment():
    """设置SSL环境变量"""
    try:
        # 设置SSL相关环境变量
        os.environ['REQUESTS_CA_BUNDLE'] = certifi.where()
        os.environ['SSL_CERT_FILE'] = certifi.where()
        os.environ['CURL_CA_BUNDLE'] = certifi.where()
        
        # 禁用某些SSL验证（仅在必要时）
        # os.environ['PYTHONHTTPSVERIFY'] = '0'
        
        return True
    except Exception as e:
        print(f"设置SSL环境变量失败: {e}")
        return False

def test_ssl_connection(url="https://www.baidu.com"):
    """测试SSL连接"""
    try:
        session = configure_requests_session()
        response = session.get(url, timeout=10)
        print(f"SSL连接测试成功: {response.status_code}")
        return True
    except Exception as e:
        print(f"SSL连接测试失败: {e}")
        return False

def init_ssl_fix():
    """初始化SSL修复"""
    try:
        print("正在初始化SSL修复...")
        
        # 1. 禁用SSL警告
        disable_ssl_warnings()
        print("✓ SSL警告已禁用")
        
        # 2. 设置环境变量
        if setup_ssl_environment():
            print("✓ SSL环境变量已设置")
        
        # 3. 修补urllib3
        if patch_urllib3_ssl():
            print("✓ urllib3 SSL已修补")
        
        # 4. 测试连接
        if test_ssl_connection():
            print("✓ SSL连接测试通过")
        
        print("SSL修复初始化完成")
        return True
        
    except Exception as e:
        print(f"SSL修复初始化失败: {e}")
        return False

# 在模块导入时自动执行SSL修复
if __name__ != "__main__":
    init_ssl_fix()